package com.oj.friend.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.oj.common.core.constants.JwtConstants;
import com.oj.common.core.domain.R;
import com.oj.common.core.domain.TableDataInfo;
import com.oj.common.core.utils.ThreadLocalUtil;
import com.oj.friend.domain.exam.ExamQuestion;
import com.oj.friend.domain.exam.dto.ExamQueryDTO;
import com.oj.friend.domain.exam.vo.ExamVO;
import com.oj.friend.domain.question.vo.QuestionDetailVO;
import com.oj.friend.manager.ExamCacheManager;
import com.oj.friend.mapper.ExamMapper;
import com.oj.friend.mapper.ExamQuestionMapper;
import com.oj.friend.mapper.UserExamMapper;
import com.oj.friend.service.IExamService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.sound.midi.Soundbank;
import java.util.List;

/**
 * @Description
 * @Author bin
 * @Date 2025/5/28
 */

@Service
public class ExamServiceImpl implements IExamService {

    @Autowired
    private ExamMapper examMapper;

    @Resource
    private ExamCacheManager examCacheManager;

    @Override
    public TableDataInfo list(ExamQueryDTO examQueryDTO) {
        PageHelper.startPage(examQueryDTO.getPageNum(), examQueryDTO.getPageSize());
        List<ExamVO> exams = examMapper.selectExamList(examQueryDTO);
        if (exams == null) {
            return TableDataInfo.empty();
        }
        return TableDataInfo.success(exams, new PageInfo<>(exams).getTotal());
    }


    @Override
    public TableDataInfo redisList(ExamQueryDTO examQueryDTO) {
        //从redis中查询数据
        // redis中没有数据时就会将数据库中的数据写入redis中  这样存在的漏洞就是redis中有部分新数据 数据库中也有部分旧数据 那么程序就无法自动将数据库中的数据同步到redis中
        // 但是上述问题可以通过限制管理员publish操作来解决 先让用户调用select接口刷新redis数据
        Long userId = ThreadLocalUtil.get(JwtConstants.LOGIN_USER_ID, Long.class);
        Long total = examCacheManager.getListSize(examQueryDTO.getType(), userId);
        TableDataInfo tableDataList;
        if (total == null || total <= 0L) {
            tableDataList = list(examQueryDTO);
            examCacheManager.refreshCache(examQueryDTO.getType(), userId);
        } else {
            List<ExamVO> examVOList = examCacheManager.getExamVOList(examQueryDTO);
            if (CollectionUtil.isEmpty(examVOList)) {
                return TableDataInfo.empty();
            }
            total = examCacheManager.getListSize(examQueryDTO.getType(), userId);
            tableDataList = TableDataInfo.success(examVOList, total);
        }
        assembleExamVOList((List<ExamVO>) tableDataList.getRows());
        return tableDataList;
    }

    @Override
    public String getFirstQuestion(Long examId) {
        Long examQuestionListSize = examCacheManager.getExamQuestionListSize(examId);
        if (examQuestionListSize <= 0) {
            // refresh
            examCacheManager.refreshExamQuestionCache(examId);
        }
        Long firstQuestionInExam = examCacheManager.getFirstQuestionInExam(examId);
        if (firstQuestionInExam == null) {
            System.out.println("firstQuestionInExam is null");
            return null;
        }
        //redis中存在e:q:l:examId
        return String.valueOf(firstQuestionInExam);

        //TODO system管理员撤销发布竞赛时需要删除redis中该竞赛的e:q:l缓存
        // 完成
    }

    @Override
    public String getNextQuestion(Long examId, Long questionId) {
        Long examQuestionListSize = examCacheManager.getExamQuestionListSize(examId);
        if (examQuestionListSize <= 0) {
            // refresh
            examCacheManager.refreshExamQuestionCache(examId);
        }
        Long nextQuestionInExam = examCacheManager.getNextQuestionInExam(examId, questionId);
        if (nextQuestionInExam == null) {
            System.out.println("nextQuestionInExam is null");
            return null;
        }
        return String.valueOf(nextQuestionInExam);
    }

    @Override
    public String getPreQuestion(Long examId, Long questionId) {
        Long examQuestionListSize = examCacheManager.getExamQuestionListSize(examId);
        if (examQuestionListSize <= 0) {
            // refresh
            examCacheManager.refreshExamQuestionCache(examId);
        }
        Long preQuestionInExam = examCacheManager.getPreQuestionInExam(examId, questionId);
        if (preQuestionInExam == null) {
            System.out.println("preQuestionInExam is null");
            return null;
        }
        return String.valueOf(preQuestionInExam);
    }

    private void assembleExamVOList(List<ExamVO> examVOList) {
        Long userId = ThreadLocalUtil.get(JwtConstants.LOGIN_USER_ID, Long.class);
        // examCache 里 查当前用户和examId的关系
        List<Long> userExamCache = examCacheManager.getUserExamCache(userId);
        if (CollectionUtil.isEmpty(userExamCache)) {
            System.out.println("userExamCache is empty");
            return;
        }
        // 根据关系设置enter字段
        for (ExamVO examVO : examVOList) {
            if (userExamCache.contains(examVO.getExamId())) {
                examVO.setEnter(true);
            }
        }
    }
}
